﻿using Orchard.ContentManagement;
using Orchard.ContentManagement.Records;
using Orchard.Core.Common.Utilities;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web;

namespace EcoTourEduca.BingYourMaps.Models
{
    public class BingMapsLocationRecord : ContentPartRecord
    {
        public BingMapsLocationRecord()
        {
        }

        public virtual string FriendlyName { get; set; }
        public virtual float Latitude { get; set; }
        public virtual float Longitude { get; set; }
        public virtual int MapHeight { get; set; }
        public virtual int? MapWidth { get; set; }
        [StringLength(4)]
        // 4 chars is enough to identify Bing Maps mode (e.g. aerial)
        public virtual string MapType { get; set; }
        public virtual int MapZoom { get; set; }
        public virtual string PinIcon { get; set; }
        public virtual bool HideMap { get; set; }

        #region Operator overrides

        /// <summary>
        /// Returns true if both BingMapsLocationRecord reference in fact to the same item.
        /// </summary>
        /// <param name="locationA"></param>
        /// <param name="locationB"></param>
        /// <returns></returns>
        public static bool operator ==(BingMapsLocationRecord locationA, BingMapsLocationRecord locationB)
        {
            if (object.ReferenceEquals(locationA, locationB))
            {
                return true;
            }

            if ((object) locationA == null || (object) locationB == null)
            {
                return false;
            }

            return locationA.Id == locationB.Id;
        }

        /// <summary>
        /// Returns false when both BingMapsLocationRecord reference different items.
        /// </summary>
        /// <param name="locationA"></param>
        /// <param name="locationB"></param>
        /// <returns></returns>
        public static bool operator !=(BingMapsLocationRecord locationA, BingMapsLocationRecord locationB)
        {
            return !(locationA == locationB);
        }

        #endregion

        #region Method overrides

        /// <summary>
        /// Overrides object.Equals(). Just for good practise... calling base.
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public override bool Equals(object obj)
        {
            return base.Equals(obj);
        }

        /// <summary>
        /// Returns hash code for the BingMapsLocation
        /// </summary>
        /// <returns></returns>
        public override int GetHashCode()
        {
            return (int) Latitude ^ (int) Longitude;
        }

        #endregion
    }
    
    public class BingMapsLocationPart : ContentPart<BingMapsLocationRecord>
    {
        #region Record mapping properties

        [Required]
        public string FriendlyName
        {
            get { return Record.FriendlyName; }
            set { Record.FriendlyName = value; }
        }

        [Required]
        public float Latitude
        {
            get { return Record.Latitude; }
            set { Record.Latitude = value; }
        }

        [Required]
        public float Longitude
        {
            get { return Record.Longitude; }
            set { Record.Longitude = value; }
        }

        [Required]
        public int MapHeight
        {
            get { return Record.MapHeight; }
            set { Record.MapHeight = value; }
        }

        public int? MapWidth
        {
            get { return Record.MapWidth; }
            set { Record.MapWidth = value; }
        }

        [Required]
        public string MapType
        {
            get { return Record.MapType; }
            set { Record.MapType = value; }
        }

        [Required]
        public int MapZoom
        {
            get { return Record.MapZoom; }
            set { Record.MapZoom = value; }
        }

        public string PinIcon
        {
            get { return Record.PinIcon; }
            set { Record.PinIcon = value; }
        }

        [Required]
        public bool HideMap
        {
            get { return Record.HideMap; }
            set { Record.HideMap = value; }
        }

        #endregion

        #region Operator overrides

        /// <summary>
        /// Returns true if both BingMapsLocationPart reference in fact to the same item.
        /// </summary>
        /// <param name="locationA"></param>
        /// <param name="locationB"></param>
        /// <returns></returns>
        public static bool operator ==(BingMapsLocationPart locationA, BingMapsLocationPart locationB)
        {
            if (object.ReferenceEquals(locationA, locationB))
            {
                return true;
            }

            if ((object) locationA == null || (object) locationB == null)
            {
                return false;
            }

            return locationA.Id == locationB.Id;
        }

        /// <summary>
        /// Returns false when both BingMapsLocationPart reference different items.
        /// </summary>
        /// <param name="locationA"></param>
        /// <param name="locationB"></param>
        /// <returns></returns>
        public static bool operator !=(BingMapsLocationPart locationA, BingMapsLocationPart locationB)
        {
            return !(locationA == locationB);
        }

        #endregion

        #region Method overrides

        /// <summary>
        /// Overrides object.Equals(). Just for good practise... calling base.
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public override bool Equals(object obj)
        {
 	         return base.Equals(obj);
        }

        /// <summary>
        /// Returns hash code for the BingMapsLocationPart
        /// </summary>
        /// <returns></returns>
        public override int GetHashCode()
        {
 	         return (int)Latitude ^ (int)Longitude;
        }

        #endregion

        #region BingMapsAreaPart associations

        //private readonly LazyField<IEnumerable<BingMapsAreaPart>> _bingMapsAreas 
        //    = new LazyField<IEnumerable<BingMapsAreaPart>>();
        //public LazyField<IEnumerable<BingMapsAreaPart>> BingMapsAreasField 
        //{ 
        //    get 
        //    { 
        //        return _bingMapsAreas; 
        //    }
        //}

        private IEnumerable<BingMapsAreaPart> _bingMapsAreas;
        public IEnumerable<BingMapsAreaPart> BingMapsAreas
        {
            get
            {
                if (_bingMapsAreas == null)
                {
                    _bingMapsAreas = new List<BingMapsAreaPart>();
                }
                return _bingMapsAreas; 
            }
            set { _bingMapsAreas = value; }
        }

        #endregion
    }
}